package com.easy.robot.task

import ai.easy.robot.task.MainWork
import ai.easy.robot.task.SubTaskQueueManager
import ai.easy.robot.utils.logd
import android.os.Bundle
import kotlinx.coroutines.experimental.*
import java.lang.ref.WeakReference
import kotlin.coroutines.experimental.CoroutineContext

/**
 * 提供任务内资源的管理，提供与TaskPool的通讯，提供任务定时器等
 */
class TaskContext(val pool: TaskPool) {

    //默认的协程上下文
    internal var cc: CoroutineContext? = null
    //当前协程上下文
    val cctx: CoroutineContext = cc ?: CommonPool

    /**
     *
     */
    @JvmOverloads
    fun startNew(taskId: String, data: Bundle? = null) {
    }

    var startData: Bundle? = null
        get() = field
        internal set(value) {
            field = value
        }

    /**
     * 创建任务内的子任务队列
     */
    fun createSubTaskQueue(): WeakReference<SubTaskQueueManager> {
        //if(!this::subTaskQueue.isInitialized) {
        if (null == subTaskQueue) {
            val s = SubTaskQueueManager(this)
            subTaskQueue = s
        }
        return WeakReference<SubTaskQueueManager>(subTaskQueue)
    }

    private var subTaskQueue: SubTaskQueueManager? = null

    internal var askJob: Job? = null

    internal fun askInterrupt(taskName: String, canResume: Boolean, after: suspend (Int) -> Unit) {
        //
        if (askJob != null) {
            return
        }
        pool.interruptComingSelector?.let { selector ->
            //开启一个异步协程获取用户的选择
            launch(cctx) {
                try {
                    askJob = launch(cctx) {
                        selector.isFinished = false
                        selector.makeSelection(taskName, canResume)
//                      //
                        var i = 0
                        while (isActive && !selector.isFinished) {
                            delay(100)
                            if (i++ > 300) {
                                break
                            }
                        }
                    }
                    askJob?.join()
                } catch (ex: Exception) {
                    ex.printStackTrace()
                    //yes = false
                } finally {
                    askJob = null
                    //
                    selector.onFinishOrCancel()
                    // TODO
                    after(selector.userChoice)
                }
            }
        }
    }

    /**
     * 释放TaskContextch创建的各种资源
     */
    fun release() {
        logd("release task context")
        //if(this::subTaskQueue.isInitialized) {
        subTaskQueue?.let {
            if (it.isFinished) {
                it.forceCancel()
            }
        }
        //任务已结束时, 用户还未选择
        askJob?.cancel()
        //
        //taskWork?.cancel()
        mainWork?.stop()

    }

    /**
     * 延时
     */
    fun delayMs(ms: Int) {
        runBlocking(cctx) {
            delay(ms.toLong())
        }
    }

    /**
     * 运行任务主要工作
     */
    private var mainWork: MainWork? = null
    fun doMainWork(work:TaskContext.()->Unit){
        mainWork= MainWork(cctx,{ work(this) })
        mainWork?.start()
    }

    /**
     * 暂停
     */
    fun pauseMainWork(){
        mainWork?.pause()
    }

    /**
     * 恢复。MainWork中将结束等待
     */
    fun resumeMainWork(){
        mainWork?.resume()
    }

    /**
     * 暂停时挂起等待
     */
    fun suspendMainWorkWhenPaused(){
        mainWork?.suspendWhenPaused()
    }

    /**
     * 延时执行
     */
    fun delayMsDo(ms: Int, work: () -> Unit) {
        runBlocking(cctx) {
            delay(ms.toLong())
            work()
        }
    }


}